/*  This file is part of -_-.

    -_- is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    -_- is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with -_-.  If not, see <http://www.gnu.org/licenses/>.

    Copyright 2012-2013 Oliver Katz */

#include "../../common/debug.h"
#include "../../arch/arch.h"
#include "../../arch/modules/mod_argbuf.h"
#include "../../arch/modules/mod_bus.h"
#include "../../arch/modules/mod_codeserver.h"
#include "../../arch/modules/mod_log.h"
#include "../../arch/modules/mod_share_client.h"
#include "../../arch/modules/mod_share_server.h"
#include "../../arch/modules/mod_ipc_client.h"
#include "../../arch/modules/mod_ipc_server.h"
#include "../../visual/script.h"
#include "../../visual/allocator.h"

using namespace sleepyface;
using namespace sleepyface::arch;
using namespace sleepyface::visual;
using namespace sleepyface::visual::script;

int main(int argc, char *argv[])
{
	Z_DEBUG_INIT(argv[0]);

	Architecture arch = Architecture("-_-visual");

	arch.loadRequiredInternals();
	arch.loadOptionalInternals(argc, argv);

	ModuleSignal s = ModuleSignal(modules::IPCServer::signalConnect);
    s.append(ModuleValue(ModuleValue::_int, 8952));
    arch.module("ipc-server")->signal(s, arch);

    Region sar = sizeBox(1024, 600);
    ScreenAllocator sa = ScreenAllocator(sar);
    map<int, ScreenAllocator> appAllocators;
    map<int, PaneManager> paneManagers;

    bool run = true;

    while(run)
    {
        z_data *req = (z_data *)arch.module("ipc-server")->get("", "", arch).getData();
        int port = arch.module("ipc-server")->get("port", "", arch).getInt();
        string ip = arch.module("ipc-server")->get("ip", "", arch).getString();
        int *rb = (int *)z_data_src_get(req);

        stringstream ss;
        Region res;

		if (rb[0] == -1)
		{
			ss << "AppSpaceRequest from " << ip << ":" << port << " (PID " << rb[1] << ")";
            sa.hint(Region(rb[2], rb[3], rb[4], rb[5]), rb[1]);
            appAllocators[rb[1]] = ScreenAllocator(sa.retrieve(rb[1]));
            paneManagers[rb[1]] = PaneManager();
            res = sa.retrieve(rb[1]);
		}
		else if (rb[0] == -2)
		{
			ss << "PaneSpaceRequest from " << ip << ":" << port << " (PID " << rb[1] << ")";
            appAllocators[rb[1]].hint(Region(rb[2], rb[3], rb[4], rb[5]), appAllocators[rb[1]].size());
            res = appAllocators[rb[1]].retrieve(appAllocators[rb[1]].size()-1);
            Region vis = Region(rb[6], rb[7], rb[8], rb[9]);
            paneManagers[rb[1]].append()
		}

        ((modules::Log *)arch.module("log"))->log(0, ss.str());

        int *buf = (int *)malloc(sizeof(int)*4);
        buf[0] = res.getX0();
        buf[1] = res.getY0();
        buf[2] = res.getX1();
        buf[3] = res.getY1();
        z_data *resd = z_data_new(Z_TYPEID_NULL, sizeof(int)*4);
        z_data_src_set(resd, buf);
		arch.module("ipc-server")->set("", "", ModuleValue(ModuleValue::_data, resd), arch);
        z_data_delete(resd);
    }

	return 0;
}
